<?php

Yii::import("application.components.evaluators.CompilerBase");

class DrivenCompiler extends CompilerBase {

    private $target;
    private $tmpDir;

    public function __construct($request) {
        parent::__construct($request);
    }

    /**
     * Membersihkan berkas-berkas temporer dari disk 
     */
    protected function afterCompile() {
        
    }

    protected function beforeCompile() {
        $this->targetFilePath = $this->getGradingDirectory() . "/" . $this->requestModel->source_file;
        file_put_contents($this->targetFilePath , $this->requestModel->file);
        
        ///Unzipping
        $tmpDir = $this->gradingDirectory;
        exec("unzip -o " . $this->targetFilePath . " -d $tmpDir");
        
        ///Injecting evaluator files
        if ($this->requestModel->evaluationset->file !== NULL) {
            file_put_contents($this->getGradingDirectory() . "/evaluator.zip" , $this->requestModel->evaluationset->file);
            exec("unzip -o " . $this->getGradingDirectory() . "/evaluator.zip -d " . $this->getGradingDirectory());
        }
    }

    /**
     * Membuat berkas script (.sh) yang dapat dipanggil untuk kemudian dieksekusi oleh grader
     */
    protected function generateExecutionScript() {
        if ($this->compileReturnValue == 0) {
            $this->executionScriptPath = $this->gradingDirectory . "/execute.sh";
            $executionCommand = $this->gradingDirectory . "/driver";
            file_put_contents($this->executionScriptPath, $executionCommand);
        } else {
            $this->executionScriptPath = "";
        }
    }

    /**
     * Mengeset target dari Makefile yang diinginkan
     * @param string $target 
     */
    public function setTarget($target) {
        $this->target = $target;
    }

    /**
     * Melakukan kompilasi, akan mengeset compileReturnValue dengan nilai kembalian proses kompilasi. 0 jika sukses, selain itu gagal.
     * Pesan kompilasi dapat diambil dari compileOutput
     * Program hasil kompilasi dapat diambil di outputFilePath
     * I.S: Direktori temporer sudah dibuat dengan Makefile di dalamnya. Jika tidak ada Makefile, return value != 0
     * F.S: compileOutput, compileReturnValue, outputFilePath terisi 
     */
    protected function doCompile() {
        $currentDir = getcwd();
        $tmpDir = $this->gradingDirectory;
        chdir($tmpDir);
        $moevalboxpath = Yii::app()->params['config']['evaluator']['sandboxpath'];
        ///Do compile process!
        //exec("make $this->target OUTPUT=$tmpDir/Main TESTER=$testerFileName -f $tmpDir/Makefile -C $tmpDir 2>&1", $out, $return);
        ///TODO: config driver.c!
        /*exec("make $this->target DRIVER=$tmpDir/driver.c DRIVER-OUTPUT=driver -f $tmpDir/Makefile -C $tmpDir 2>&1", $out, $return);
        
        $this->compileOutput = implode("\n", $out);
        $this->compileReturnValue = $return;

        if ($return == 0) {
            $this->outputFilePath = $tmpDir . "/driver";
        }
        else {
            $this->outputFilePath = "";
        }*/
        if (file_exists("compile.sh")) {
            exec("$moevalboxpath -e -t 5 -- /bin/sh compile.sh 2>&1" , $output , $return);
            
            $this->compileReturnValue = $return;
            if ($return == 0) {
                $this->compileOutput = "Compile success\n";
                $this->outputFilePath = $output[0];
            }
            else {
                $this->outputFilePath = "";
            }
            $this->compileOutput .= file_get_contents("compile.info");
        }
        else {
            $this->compileReturnValue = -1;
            $this->outputFilePath = "";
            $this->compileOutput = "Failed to locate compile.sh";
        }
        chdir($currentDir);
    }

}

?>
